package com.ioc.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 0 导入jar包：
 * <dependencies>
 *         <dependency>
 *             <groupId>org.aspectj</groupId>
 *             <artifactId>aspectjweaver</artifactId>
 *             <version>1.9.6</version>
 *         </dependency>
 *     </dependencies>
 *
 * 1 Spring需要手动开启AOP支持，@EnableAspectJAutoProxy//手动开启AOP支持
 * 2 通知类，拦截器类，也叫增强类，也叫切面类，需要加@Aspect
 * 3 通知类型/拦截器类型
 *   * @Before前置通知/拦截器
 *   * @After 后置通知/拦截器
 *   * @Around 环绕通知/拦截器
 *   * @AfterReturning 返回后通知/拦截器
 *   * @AfterThrowing 抛出异常通知/拦截器
 *
 */
@Component
@Aspect
public class MyFristAdvice {

    //配置切入点
    @Pointcut("execution(* *..*())")
//    @Pointcut("execution(void com.ioc.dao.UserDao.save())")
    private void pt(){}


    @Before("pt()")//在执行目标方法前执行
    public void beforeLog(){
        System.out.println("before:"+new Date().toString());
    }

    @After("pt()")//目标方法执行完毕执行
    public void afterLog(){
        System.out.println("after:"+new Date().toString());
    }

    /**
     * 需要手动调用目标对象
     */
    @Around("pt()")//目标方法执行的前后都执行
    public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
        System.out.println("around前:"+new Date().toString());

        Object proceed = point.proceed();

        System.out.println("around后:"+new Date().toString());
        return proceed;
    }

    @AfterReturning("pt()")//目标方法执行完毕后返回的时候执行，且不出异常
    public void afterReturningLog(){
        System.out.println("afterReturning:"+new Date().toString());
    }
    @AfterThrowing("pt()")//目标方法执行的过程中，如果发生异常执行
    public void afterThrowingLog(){
        System.out.println("afterThrowing:"+new Date().toString());
    }





}
